// 俄罗斯方块AI逻辑
class TetrisAI {
    constructor(game) {
        this.game = game;
        this.aiEnabled = false;
        this.aiInterval = null;
    }
    
    // 启用AI
    enableAI() {
        if (!this.aiEnabled) {
            this.aiEnabled = true;
            document.getElementById('aiBtn').classList.add('active');
            debugger ;
            // 设置AI思考和执行的间隔
            this.aiInterval = setInterval(() => {
                if (!this.game.paused && !this.game.gameOver) {
                    this.makeBestMove();
                }
            }, 200); // AI每200毫秒做出一次决策
        }
    }
    
    // 禁用AI
    disableAI() {
        if (this.aiEnabled) {
            this.aiEnabled = false;
            document.getElementById('aiBtn').classList.remove('active');
            
            if (this.aiInterval) {
                clearInterval(this.aiInterval);
                this.aiInterval = null;
            }
        }
    }
    
    // 切换AI状态
    toggleAI() {
        if (this.aiEnabled) {
            this.disableAI();
        } else {
            this.enableAI();
        }
    }
    
    // 做出最佳移动
    makeBestMove() {
        const gameState = this.game.getGameState();
        let bestMove = null;
        let bestScore = -Infinity;
        
        console.log('==== AI开始思考最佳移动 ====');
        console.log(`当前方块类型: ${gameState.currentPiece.type}`);
        
        // 尝试所有可能的旋转
        const rotations = this.getPossibleRotations(gameState.currentPiece);
        console.log(`找到 ${rotations.length} 种可能的旋转方式`);

        for (const rotation of rotations) {
            // 尝试所有可能的水平位置
            // 对于I型方块，需要特殊处理边界检测
            const minX = 0;
            let maxX = gameState.cols - rotation.shape[0].length;
            
            // 特殊处理I型方块（类型1），确保它可以到达最右边的边界
            if (gameState.currentPiece.type === 1) {  // I型方块
                // I型方块旋转后仍然是4格宽，但需要能够接触到最右边的边界
                maxX = gameState.cols - Math.min(rotation.shape[0].length, 4);
            }
            
            for (let x = minX; x <= maxX; x++) {
                // 创建模拟的游戏板来评估这个位置
                const simulatedBoard = this.cloneBoard(gameState.board);
                const simulatedPiece = {
                    ...gameState.currentPiece,
                    shape: rotation.shape,
                    x: x,
                    y: 0
                };
                
                // 先将方块下落到合适的位置，再计算消除行数
                this.dropPieceToBottom(simulatedBoard, simulatedPiece, gameState.cols, gameState.rows);
                
                // 将方块固定到模拟的游戏板上
                this.lockPieceToBoard(simulatedBoard, simulatedPiece);
                
                // 计算这个位置可能消除的行数
                const clearedLines = this.calculateClearedLines(simulatedBoard);
                
                // 计算这个位置的评分
                const score = this.calculateScore(simulatedBoard, gameState.cols, gameState.rows, clearedLines);
                
                console.log(`评估: 旋转 ${rotation.rotations} 次, X位置 ${x}, 预计消除行数 ${clearedLines}, 评分 ${score.toFixed(2)}`);
                
                // 更新最佳移动
                if (score > bestScore) {
                    bestScore = score;
                    bestMove = {
                        rotation: rotation.rotations,
                        x: x
                    };
                    console.log(`  找到更好的移动方案: 旋转 ${bestMove.rotation} 次, X位置 ${bestMove.x}, 评分 ${bestScore.toFixed(2)}`);
                }
            }
        }
        
        // 执行最佳移动
        if (bestMove) {
            console.log(`\n最终决定: 旋转 ${bestMove.rotation} 次, 移动到X位置 ${bestMove.x}`);
            this.executeMove(bestMove);
        }
        console.log('==== AI思考结束 ====\n');
    }
    
    // 执行最佳移动
    executeMove(move) {
        // 先保存当前方块的原始位置
        const originalX = this.game.currentPiece.x;
        
        console.log(`\n开始执行移动: 原始X位置 ${originalX}`);
        
        // 旋转方块到最佳角度
        if (move.rotation > 0) {
            console.log(`执行 ${move.rotation} 次旋转`);
            for (let i = 0; i < move.rotation; i++) {
                this.game.rotatePiece();
            }
        }
        
        // 旋转后，重新计算需要移动的距离
        const currentX = this.game.currentPiece.x;
        const targetX = move.x;
        const distance = targetX - currentX;
        
        console.log(`旋转后X位置 ${currentX}, 目标X位置 ${targetX}, 需要移动 ${distance > 0 ? '右' : distance < 0 ? '左' : '不移动'} ${Math.abs(distance)} 格`);
        
        // 移动方块到最佳水平位置，确保不发生碰撞
        if (distance < 0) {
            // 需要向左移动
            let moved = 0;
            for (let i = 0; i < Math.abs(distance); i++) {
                // 特殊处理I型方块，确保它可以移动到最左边
                if (this.game.currentPiece.type === 1 && this.game.currentPiece.x <= 0) {
                    break; // I型方块已经到最左边
                }
                if (this.game.checkCollision(this.game.currentPiece, -1, 0)) {
                    console.log(`  向左移动受阻，已移动 ${moved} 格`);
                    break; // 如果会发生碰撞，停止移动
                }
                this.game.movePieceLeft();
                moved++;
            }
            console.log(`完成向左移动 ${moved} 格`);
        } else if (distance > 0) {
            // 需要向右移动
            let moved = 0;
            for (let i = 0; i < distance; i++) {
                // 特殊处理I型方块，确保它可以移动到最右边
                if (this.game.currentPiece.type === 1) {
                    // 检查I型方块是否已经到达右边界
                    const pieceRightEdge = this.game.currentPiece.x + this.game.currentPiece.shape[0].length;
                    if (pieceRightEdge >= this.game.cols) {
                        break; // I型方块已经到最右边
                    }
                }
                if (this.game.checkCollision(this.game.currentPiece, 1, 0)) {
                    console.log(`  向右移动受阻，已移动 ${moved} 格`);
                    break; // 如果会发生碰撞，停止移动
                }
                this.game.movePieceRight();
                moved++;
            }
            console.log(`完成向右移动 ${moved} 格`);
        }
        
        // 快速下落到底部
        console.log('执行快速下落到底部');
        
        // 保存下落前的游戏板状态，用于计算实际消除的行数
        const boardBeforeDrop = this.cloneBoard(this.game.board);
        const pieceBeforeDrop = { ...this.game.currentPiece };
       
        // this.game.hardDrop();
       this.game.movePieceDown();
       this.game.movePieceDown();

        // 计算实际消除的行数
        const actualClearedLines = this.calculateClearedLines(boardBeforeDrop);
        console.log(`移动后实际消除行数: ${actualClearedLines}`);
    }
    
    // 获取方块的所有可能旋转
    getPossibleRotations(piece) {
        const rotations = [];
        const originalShape = piece.shape;
        let currentShape = originalShape;
        
        // 尝试最多4种旋转（有些方块旋转4次后会回到原始形状）
        for (let i = 0; i < 4; i++) {
            // 检查这个旋转是否已经存在（避免重复）
            let exists = false;
            for (const existing of rotations) {
                if (this.shapesEqual(currentShape, existing.shape)) {
                    exists = true;
                    break;
                }
            }
            
            if (!exists) {
                // 创建模拟的游戏板和方块来检查消除行数
                const simulatedBoard = this.cloneBoard(this.game.board);
                const simulatedPiece = {
                    ...piece,
                    shape: currentShape,
                    x: piece.x,
                    y: piece.y
                };
                
                // 考虑墙踢机制：如果旋转后发生碰撞，尝试调整位置
                // 这里模拟游戏中的墙踢逻辑
                const originalX = simulatedPiece.x;
                const originalY = simulatedPiece.y;
                
                // 检查旋转后是否发生碰撞
                if (this.checkCollision(simulatedBoard, simulatedPiece, 0, 0, this.game.cols, this.game.rows)) {
                    // 特殊处理I型方块的墙踢
                    if (piece.type === 1) {  // I型方块
                        // 尝试多种墙踢位置
                        const kicks = [
                            {x: -1, y: 0},  // 向左1格
                            {x: -2, y: 0},  // 向左2格
                            {x: 1, y: 0},   // 向右1格
                            {x: 2, y: 0},   // 向右2格
                            {x: 0, y: -1},  // 向上1格
                            {x: -1, y: -1}, // 向左1格并向上1格
                            {x: 1, y: -1}   // 向右1格并向上1格
                        ];
                        
                        let kicked = false;
                        for (const kick of kicks) {
                            simulatedPiece.x = originalX + kick.x;
                            simulatedPiece.y = originalY + kick.y;
                            
                            if (!this.checkCollision(simulatedBoard, simulatedPiece, 0, 0, this.game.cols, this.game.rows)) {
                                kicked = true;
                                break;
                            }
                        }
                        
                        // 如果所有墙踢都失败，恢复原状
                        if (!kicked) {
                            simulatedPiece.x = originalX;
                            simulatedPiece.y = originalY;
                        }
                    } else {
                        // 其他方块的标准墙踢逻辑
                        // 尝试墙踢：向左移动1格
                        simulatedPiece.x--;
                        if (this.checkCollision(simulatedBoard, simulatedPiece, 0, 0, this.game.cols, this.game.rows)) {
                            // 向左移动不行，尝试向右移动2格（恢复原位后再向右移动1格）
                            simulatedPiece.x += 2;
                            if (this.checkCollision(simulatedBoard, simulatedPiece, 0, 0, this.game.cols, this.game.rows)) {
                                // 向右移动不行，尝试向上移动1格
                                simulatedPiece.x = originalX;
                                simulatedPiece.y--;
                                if (this.checkCollision(simulatedBoard, simulatedPiece, 0, 0, this.game.cols, this.game.rows)) {
                                    // 所有墙踢尝试都失败，恢复原状
                                    simulatedPiece.x = originalX;
                                    simulatedPiece.y = originalY;
                                }
                            }
                        }
                    }
                }
                
                // 确保方块不会移动到游戏板左侧之外
                while (this.checkCollision(simulatedBoard, simulatedPiece, 0, 0, this.game.cols, this.game.rows)) {
                    simulatedPiece.x++;
                    if (simulatedPiece.x > this.game.cols) {
                        // 如果无法避免碰撞，恢复原状
                        simulatedPiece.x = originalX;
                        simulatedPiece.y = originalY;
                        break;
                    }
                }
                
                // 再次检查是否在游戏板右侧之外，并调整位置
                let adjusted = false;
                while (simulatedPiece.x + simulatedPiece.shape[0].length > this.game.cols) {
                    simulatedPiece.x--;
                    adjusted = true;
                    // 如果调整后仍然超出边界，则恢复原状
                    if (simulatedPiece.x < 0) {
                        simulatedPiece.x = originalX;
                        simulatedPiece.y = originalY;
                        break;
                    }
                }
                
                // 如果进行了调整，再次检查碰撞
                if (adjusted && this.checkCollision(simulatedBoard, simulatedPiece, 0, 0, this.game.cols, this.game.rows)) {
                    // 如果调整后仍有碰撞，恢复原状
                    simulatedPiece.x = originalX;
                    simulatedPiece.y = originalY;
                }
                
                // 计算方块落到底部后的位置
                this.dropPieceToBottom(simulatedBoard, simulatedPiece, this.game.cols, this.game.rows);
                
                // 将方块固定到模拟的游戏板上
                this.lockPieceToBoard(simulatedBoard, simulatedPiece);
                
                // 计算这个旋转可能消除的行数
                const clearedLines = this.calculateClearedLines(simulatedBoard);
                
                rotations.push({
                    shape: currentShape,
                    rotations: i,
                    clearedLines: clearedLines
                });
            }
            
            // 旋转方块
            currentShape = this.rotateShape(currentShape);
        }
        
        return rotations;
    }
    
    // 旋转形状矩阵
    rotateShape(shape) {
        const rows = shape.length;
        const cols = shape[0].length;
        const rotated = [];
        
        for (let i = 0; i < cols; i++) {
            rotated[i] = [];
            for (let j = 0; j < rows; j++) {
                rotated[i][j] = shape[rows - 1 - j][i];
            }
        }
        
        return rotated;
    }
    
    // 检查两个形状是否相同
    shapesEqual(shape1, shape2) {
        if (shape1.length !== shape2.length) return false;
        
        for (let y = 0; y < shape1.length; y++) {
            if (shape1[y].length !== shape2[y].length) return false;
            
            for (let x = 0; x < shape1[y].length; x++) {
                if (shape1[y][x] !== shape2[y][x]) return false;
            }
        }
        
        return true;
    }
    
    // 克隆游戏板
    cloneBoard(board) {
        return board.map(row => [...row]);
    }
    
    // 将方块落到模拟游戏板的底部
    dropPieceToBottom(board, piece, cols, rows) {
        // 特殊处理I型方块，确保它可以正确下落到边界
        while (!this.checkCollision(board, piece, 0, 1, cols, rows)) {
            piece.y++;
        }
    }
    
    // 检查碰撞
    checkCollision(board, piece, offsetX = 0, offsetY = 0, cols, rows) {
        for (let y = 0; y < piece.shape.length; y++) {
            for (let x = 0; x < piece.shape[y].length; x++) {
                if (piece.shape[y][x] !== 0) {
                    const newX = piece.x + x + offsetX;
                    const newY = piece.y + y + offsetY;
                    
                    // 特殊处理I型方块的边界检测
                    if (piece.type === 1) {  // I型方块
                        // 确保I型方块不会超出左右边界
                        if (newX < 0 || newX >= cols) {
                            return true;
                        }
                        
                        // 确保I型方块不会超出底部边界
                        if (newY >= rows) {
                            return true;
                        }
                        
                        // 检查与已存在方块的碰撞
                        if (newY >= 0 && board[newY][newX] !== 0) {
                            return true;
                        }
                    } else {
                        // 其他方块的标准碰撞检测
                        if (
                            newX < 0 || 
                            newX >= cols || 
                            newY >= rows || 
                            (newY >= 0 && board[newY][newX] !== 0)
                        ) {
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }
    
    // 将方块固定到模拟的游戏板上
    lockPieceToBoard(board, piece) {
        for (let y = 0; y < piece.shape.length; y++) {
            for (let x = 0; x < piece.shape[y].length; x++) {
                if (piece.shape[y][x] !== 0) {
                    const boardY = piece.y + y;
                    const boardX = piece.x + x;
                    
                    // 特殊处理I型方块的边界情况
                    if (piece.type === 1) {  // I型方块
                        // 确保方块在游戏板范围内
                        if (boardY >= 0 && boardY < board.length && boardX >= 0 && boardX < board[0].length) {
                            board[boardY][boardX] = piece.shape[y][x];
                        }
                    } else {
                        // 其他方块的标准处理
                        if (boardY >= 0 && boardY < board.length && boardX >= 0 && boardX < board[0].length) {
                            board[boardY][boardX] = piece.shape[y][x];
                        }
                    }
                }
            }
        }
    }
    
    // 计算消除的行数
    calculateClearedLines(board) {
        // 克隆当前游戏板，避免修改原始游戏板
        const tempBoard = this.cloneBoard(board);
        
        let linesCleared = 0;
        
        // 从底部向上检查每一行，模拟实际游戏的消行逻辑
        for (let y = tempBoard.length - 1; y >= 0; y--) {
            // 检查这一行是否完全填满
            let isFull = true;
            for (let x = 0; x < tempBoard[y].length; x++) {
                if (tempBoard[y][x] === 0) {
                    isFull = false;
                    break;
                }
            }
            
            if (isFull) {
                // 移除已满的行
                tempBoard.splice(y, 1);
                // 在顶部添加新的空行
                tempBoard.unshift(Array(tempBoard[0].length).fill(0));
                // 由于移除了一行，需要重新检查当前位置
                y++;
                linesCleared++;
            }
        }
        
        return linesCleared;
    }
    
    // 计算底部紧凑度（不给下方留下空格，越高越好）
    calculateBottomCompactness(board, cols, rows) {
        let compactness = 0;
        
        for (let x = 0; x < cols; x++) {
            let bottomEmptyRows = 0;
            let foundBlock = false;
            
            // 从底部向上检查，计算底部连续的空行数
            for (let y = rows - 1; y >= 0; y--) {
                if (board[y][x] !== 0) {
                    foundBlock = true;
                    break;
                } else {
                    bottomEmptyRows++;
                }
            }
            
            // 如果这一列有方块，且底部没有空格，得分最高
            if (foundBlock && bottomEmptyRows === 0) {
                compactness += 1;
            }
            // 如果有少量底部空格，得分中等
            else if (foundBlock && bottomEmptyRows <= 2) {
                compactness += 0.5;
            }
            // 如果底部空格太多，得分较低
            else if (foundBlock) {
                compactness += 0.1;
            }
        }
        
        return compactness;
    }
    
    // 计算方块平滑度（确保新方块本身不给后面的方块留下空格，越高越好）
    calculateBlockSmoothness(board, cols, rows) {
        let smoothness = 0;
        
        // 检查每一行的方块分布是否平滑，避免在方块上方或中间留下不规则空格
        for (let y = 0; y < rows; y++) {
            let leftmostBlock = cols;
            let rightmostBlock = -1;
            let blockCount = 0;
            
            // 找出这一行中最左边和最右边的方块位置
            for (let x = 0; x < cols; x++) {
                if (board[y][x] !== 0) {
                    leftmostBlock = Math.min(leftmostBlock, x);
                    rightmostBlock = Math.max(rightmostBlock, x);
                    blockCount++;
                }
            }
            
            // 如果这一行有方块
            if (blockCount > 0) {
                // 计算这一行中实际填充的方块数与理想连续方块数的比率
                const expectedBlocks = rightmostBlock - leftmostBlock + 1;
                const rowSmoothness = blockCount / expectedBlocks;
                smoothness += rowSmoothness;
                
                // 特别奖励完全连续的行
                if (rowSmoothness === 1) {
                    smoothness += 0.5;
                }
            }
        }
        
        // 检查列之间的高度差异，避免形成锯齿状的顶部
        const heights = this.calculateHeights(board, cols, rows);
        for (let x = 1; x < cols; x++) {
            const heightDiff = Math.abs(heights[x] - heights[x - 1]);
            // 高度差异越小，平滑度越高
            smoothness += (4 - Math.min(heightDiff, 4)) * 0.2;
        }
        
        return smoothness;
    }
    
    // 计算位置评分
    calculateScore(board, cols, rows, clearedLines) {
        let score = 0;
        
        // 计算堆积高度（越低越好）
        const heights = this.calculateHeights(board, cols, rows);
        const avgHeight = heights.reduce((a, b) => a + b, 0) / heights.length;
        const maxHeight = Math.max(...heights);
        
        // 计算行的完整度（越高越好）
        const rowCompleteness = this.calculateRowCompleteness(board, cols, rows);
        
        // 计算空洞数量（越少越好）
        const holes = this.calculateHoles(board, cols, rows, heights);
        
        // 计算粗糙度（相邻列高度差的总和，越小越好）
        const roughness = this.calculateRoughness(heights);
        
        // 计算行转换次数（方块堆叠的水平变化次数，越少越好）
        const rowTransitions = this.calculateRowTransitions(board, cols, rows);
        
        // 计算底部紧凑度（不给下方留下空格，越高越好）
        const bottomCompactness = this.calculateBottomCompactness(board, cols, rows);
        
        // 计算方块平滑度（新方块本身不给后面的方块留下空格，越高越好）
        const blockSmoothness = this.calculateBlockSmoothness(board, cols, rows);
        
        // 计算井坑数量（越少越好）
        const wells = this.calculateWells(heights);
        
        // 评分公式（权重可以调整）
        score += clearedLines * 50;        // 消除行数（权重大幅增加）
        score += bottomCompactness * 15;   // 底部紧凑度
        score += blockSmoothness * 5;      // 方块平滑度
        score -= avgHeight * 10;           // 平均高度
        score -= maxHeight * 5;            // 最大高度
        score += rowCompleteness * 3;      // 行的完整度
        score -= holes * 40;               // 空洞数量
        score -= roughness * 2;            // 粗糙度
        score -= rowTransitions * 1;       // 行转换次数
        score -= wells * 10;               // 井坑数量
        
        console.log(`clearedLines:${clearedLines}, avgHeight:${avgHeight.toFixed(1)}, maxHeight:${maxHeight}, holes:${holes}, roughness:${roughness}`);
        
        return score;
    }
    
    // 计算每列的高度
    calculateHeights(board, cols, rows) {
        const heights = [];
        
        for (let x = 0; x < cols; x++) {
            let height = 0;
            // 从顶部到底部检查，计算实际高度（有方块的行数）
            for (let y = 0; y < rows; y++) {
                if (board[y][x] !== 0) {
                    // 高度是从底部到第一个方块的距离
                    height = rows - y;
                    break;
                }
            }
            heights.push(height);
        }
        
        return heights;
    }
    
    // 计算行的完整度
    calculateRowCompleteness(board, cols, rows) {
        let completeness = 0;
        
        for (let y = 0; y < rows; y++) {
            const filledCells = board[y].filter(cell => cell !== 0).length;
            completeness += filledCells / cols;
        }
        
        return completeness;
    }
    
    // 计算空洞数量
    calculateHoles(board, cols, rows, heights) {
        let holes = 0;
        
        for (let x = 0; x < cols; x++) {
            // 从底部开始，计算到有方块的位置
            const height = heights[x];
            const startY = rows - height;
            
            for (let y = rows - 1; y >= startY; y--) {
                if (board[y][x] === 0) {
                    holes++;
                }
            }
        }
        
        return holes;
    }
    
    // 计算粗糙度
    calculateRoughness(heights) {
        let roughness = 0;
        
        for (let i = 1; i < heights.length; i++) {
            roughness += Math.abs(heights[i] - heights[i - 1]);
        }
        
        return roughness;
    }
    
    // 计算行转换次数
    calculateRowTransitions(board, cols, rows) {
        let transitions = 0;
        
        for (let y = 0; y < rows; y++) {
            let prevCell = board[y][0] !== 0;
            for (let x = 1; x < cols; x++) {
                const currentCell = board[y][x] !== 0;
                if (currentCell !== prevCell) {
                    transitions++;
                    prevCell = currentCell;
                }
            }
        }
        
        return transitions;
    }
    
    // 计算井坑数量（两堵墙之间向下的开口，越少越好）
    calculateWells(heights) {
        let wells = 0;
        
        for (let i = 0; i < heights.length; i++) {
            let leftHeight = 0;
            let rightHeight = 0;
            
            // 获取左边相邻列的高度
            if (i > 0) {
                leftHeight = heights[i - 1];
            }
            
            // 获取右边相邻列的高度
            if (i < heights.length - 1) {
                rightHeight = heights[i + 1];
            }
            
            // 如果当前列比左右两列都低，则形成一个井坑
            if (heights[i] < leftHeight && heights[i] < rightHeight) {
                // 井坑深度是两边较低的那一边与当前列的高度差
                const wellDepth = Math.min(leftHeight, rightHeight) - heights[i];
                wells += wellDepth;
            }
        }
        
        return wells;
    }
}
